package com.zjitc;

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
import java.util.Arrays;
import redis.clients.jedis.Jedis;
import redis.clients.jedis.JedisCommands;
import redis.clients.jedis.JedisPool;
/**
 A.创建一个实现接口InvocationHandler的类，他必须实现invoke方法
 B.创建被代理的类以及接口。
 C.通过Proxy的静态方法newProxyInstance（ClassLoader loader，Class【】interfaces，InvocationHandler handler）创建一个代理
 D.通过代理调用方法。
 java动态代理：是在运行是生成的class对象，在生成时必须提供一组或一个interface给它，
 然后该class就宣称它实现了这些interface。你当然可以把该class的实例当做这些interface中的任何一个来用，
 当然，这个DynamicProxy其实就是一个Proxy，他不会替你做实质性的工作，在生成它的实例时你必须提供一个handler，
 由它接管实际的工作。因此，DynamicProxy必须实现InvocationHandler接口。
 5）	一个动态代理了和一个InvocationHandler 实现关联的。
 每一个动态代理实例的调用都要通过InvocationHandler接口的handler（调用处理器）来调用，
 动态代理不做任何执行操作，只是在创建动态代理时，把要实现的接口和handler关联，动态代理要帮助被代理执行的任务，
 要转交给handler来执行。其实就是调用invoke方法。
 */

/**
 * Create by IntelliJ IDEA
 *
 * @author: jsonor
 * @date-Time: 2018/4/10 16:10
 * @description:
 */
public class JedisProxy implements InvocationHandler {
  /**
   * 被代理对象：JedisCommands target
   * 在哪里？
   * JedisPool pool中。
   */
  private JedisCommands target;
  private JedisPool pool;

   public JedisCommands getInstance(JedisPool pool){
    this.pool = pool;
    this.target = pool.getResource();
    Class clazz = target.getClass();
    System.out.println(Arrays.toString(clazz.getInterfaces()));
    Object obj = Proxy.newProxyInstance(clazz.getClassLoader(), clazz.getInterfaces(), this);
     return (JedisCommands)obj;
  }

  @Override
  public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
    try {
      return method.invoke(this.target, args);
    } finally {//instanceof:判断一个对象是否属于一个类
               //第一个参数是target,也就是被代理类的对象；第二个参数是方法中的参数
      if (this.target instanceof Jedis) {
        pool.returnResource((Jedis) target);
        System.out.println("release the jedis connection");
      }
    }
  }

  public static void main(String[]args) {

  }
}

